﻿namespace Busconeitor.Domain.Entities
{
    using System;
    using Utils.SimpleList;
    
    public class TerminoSucioEntity : IComparable
    {
        #region Atributos

        private int _idTerminoSucio;

        /// <summary>
        /// Palabra con los signos de puntuacion 
        /// </summary>
        private string _palabra = string.Empty;

        /// <summary>
        /// Todos los indices dentro del documento
        /// </summary>
        private SimpleList _indices = new SimpleList();

        /// <summary>
        /// Cantidad de documentos en los que aparece el termino
        /// </summary>
        private int _idTermino;

        #endregion

        #region Constructores

        /// <summary>
        /// Constructor por parametros que inicializa los atributos de la clase. 
        /// </summary>
        /// <param name="palabra">palabra</param>
        /// <param name="idPalabraLimpia">idPalabraLimpia</param>
        public TerminoSucioEntity(String palabra, int idPalabraLimpia)
        {
            this._palabra = palabra;
            this._idTermino = idPalabraLimpia;
        }

        /// <summary>
        /// Constructor por parametros que inicializa los atributos de la clase. 
        /// </summary>
        /// <param name="palabra">palabra</param>
        public TerminoSucioEntity(String palabra)
        {
            this._palabra = palabra;
        }

        /// <summary>
        /// Constructor por parametros que inicializa los atributos de la clase. 
        /// </summary>
        /// <param name="pIndex">pIndex</param>
        /// <param name="pPalabra">pPalabra</param>
        public TerminoSucioEntity(int pIndex, String pPalabra)
        {
            _palabra = pPalabra;
            AgregarIndice(pIndex);
        }

        #endregion

        #region Propiedades

        /// <summary>
        /// Identificador del termino. 
        /// </summary>
        public int IdTerminoVariado
        {
            get { return _idTerminoSucio; }
            set { _idTerminoSucio = value; }
        }

        /// <summary>
        /// Lista simple con los indices de aparicion dentro del documento del termino.
        /// </summary>
        public SimpleList Indices
        {
            get { return _indices; }
            set { _indices = value; }
        }

        /// <summary>
        /// Cadena que contiene el termino con los signos de puntuacion.
        /// </summary>
        public string PalabraVariada
        {
            get { return _palabra; }
            set { _palabra = value; }
        }

        /// <summary>
        /// Identificador de la palabra sin signos de puntuacion a la que el termino actual esta asociado.
        /// </summary>
        public int IdTerminoLimpio
        {
            get { return _idTermino; }
            set { _idTermino = value; }
        }

        #endregion
        
        #region Metodos

        /// <summary>
        /// Agrega un nuevo indice de aparicion del termino dentro del documento. 
        /// </summary>
        /// <param name="indice">entero que representa el indice de aparicion a agregar.</param>
        public void AgregarIndice(int indice)
        {
            _indices.AddFirst(indice);
        }

        /// <summary>
        /// Redefine el metodo equals para adaptarlo a la clase PalabraVariada.
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public override bool Equals(Object obj)
        {
            if (obj == null)
            {
                return false;
            }

            if (GetType() != obj.GetType())
            {
                return false;
            }

            var other = (TerminoSucioEntity)obj;

            if ((_palabra == null) ? (other._palabra != null) : !_palabra.Equals(other._palabra))
            {
                return false;
            }

            return true;
        }
        
        /// <summary>
        /// Redefine el metodo hashCode para adaptarlo a la clase PalabraVariada.
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode() 
        {
            return Math.Abs(_palabra.GetHashCode());
        }

        /// <summary>
        /// Redefine el metodo compareTo() para adaptarlo a la clase PalabraVariada.
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public int CompareTo(object obj)
        {
            var otro = ((TerminoSucioEntity)obj).PalabraVariada;
            return _palabra.CompareTo(otro);
        }

        #endregion
    }
}
